1 module hip.filesystem.systems.cstd; 2 import hip.api.filesystem.hipfs; 3 4 5 /** 6 * All those string allocations should be removed or turnt into @nogc somehow. The better cached, the best. 7 * 8 */ 9 class HipCStdioFileSystemInteraction : IHipFileSystemInteraction 10 { 11 version(Windows) 12 pragma(lib, "Shlwapi.lib"); //PathIsDirectory 13 bool read(string path, FileReadResult delegate(ubyte[] data) onSuccess, void delegate(string err) onError) 14 { 15 import core.stdc.stdio; 16 import hip.error.handler; 17 import hip.util.conv; 18 if(ErrorHandler.assertLazyErrorMessage(exists(path), "FileSystem Error:", "Filed named '"~path~"' does not exists")) 19 return false; 20 21 auto f = fopen((path~"\0").ptr, "rb"); 22 if(f is null) 23 { 24 onError("File not found."); 25 return false; 26 } 27 if(fseek(f, 0, SEEK_END)) 28 { 29 fclose(f); 30 onError("Could not seek to file end."); 31 return false; 32 } 33 auto size = ftell(f); 34 35 if(size <= 0) 36 { 37 fclose(f); 38 onError("Size <= 0 on file "~path); 39 return false; 40 } 41 if(fseek(f, 0, SEEK_SET)) 42 { 43 fclose(f); 44 onError("Could not seek to file beginning"); 45 return false; 46 } 47 import hip.util.array; 48 ubyte[] output = uninitializedArray!(ubyte[])(size); 49 50 if(size_t readed = fread(cast(void*)output.ptr, 1, cast(size_t)size, f) != size) 51 { 52 fclose(f); 53 onError("File is corrupted. Could not read file entirely (Readed "~to!string(readed)~") Expected "~to!string(size)); 54 return false; 55 } 56 fclose(f); 57 onSuccess(output); 58 return true; 59 } 60 bool write(string path, const(void)[] data) 61 { 62 import core.stdc.stdio; 63 if(exists(path)) 64 { 65 auto file = fopen(cachedStringz(path), "w"); 66 scope(exit) 67 fclose(file); 68 if(fwrite(data.ptr, 1, data.length, file) != data.length) 69 { 70 return fflush(file) == 0; 71 } 72 return true; 73 } 74 return false; 75 } 76 bool exists(string path) 77 { 78 import core.stdc.stdio; 79 if(auto file = fopen(cachedStringz(path), "r")) 80 { 81 fclose(file); 82 return true; 83 } 84 return false; 85 } 86 bool remove(string path) 87 { 88 static import core.stdc.stdio; 89 if(exists(path)) 90 { 91 return core.stdc.stdio.remove(cachedStringz(path)) == 0; 92 } 93 94 return false; 95 } 96 97 version(Windows) 98 { 99 private alias BOOL = int; 100 private alias LPCSTR = const(char)*; 101 extern(Windows) BOOL PathIsDirectoryA(LPCSTR); 102 } 103 104 bool isDir(string path) 105 { 106 version(Windows) 107 { 108 return PathIsDirectoryA(cachedStringz(path)) == 1; 109 } 110 else version(Posix) 111 { 112 import core.sys.posix.sys.stat; 113 stat_t st; 114 stat(cachedStringz(path), &st); 115 return S_ISDIR(st.st_mode); 116 } 117 else return path[$-1] == '/'; 118 } 119 120 }